package cn.stimd.spring.aop.framework;

import cn.stimd.spring.beans.BeansException;
import org.springframework.cglib.proxy.Callback;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.Factory;
import org.springframework.objenesis.SpringObjenesis;

/**
 * 基于Objenesis的CglibAopProxy扩展，可以不通过构造函数来创建代理对象
 * <p>
 * Created by Stimd
 * 项目地址：https://gitee.com/stimd/spring-wheel
 * 公众号：Java编程探微
 */
public class ObjenesisCglibAopProxy extends CglibAopProxy {
    private static final SpringObjenesis objenesis = new SpringObjenesis();

    public ObjenesisCglibAopProxy(AdvisedSupport advised) {
        super(advised);
    }

    @Override
    protected Object createProxyClassAndInstance(Enhancer enhancer, Callback[] callbacks) {
        Class<?> proxyClass = enhancer.createClass();
        Object proxyInstance = null;

        if (objenesis.isWorthTrying()) {
            proxyInstance = objenesis.newInstance(proxyClass, enhancer.getUseCache());
        }

        if (proxyInstance == null) {
            try {
                proxyInstance = proxyClass.newInstance();
            } catch (Throwable ex) {
                throw new BeansException("无法使用Objenesis来创建代理对象");
            }
        }

        ((Factory) proxyInstance).setCallbacks(callbacks);
        return proxyInstance;
    }
}
